package com.amar.dtadmin.apidoc.util;

import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiAnnotationMemberValue;
import com.intellij.psi.PsiArrayInitializerMemberValue;
import com.intellij.psi.PsiClassObjectAccessExpression;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiEnumConstant;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiLiteralExpression;
import com.intellij.psi.PsiModifierList;
import com.intellij.psi.PsiNameValuePair;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiTypeElement;
import com.intellij.psi.impl.JavaConstantExpressionEvaluator;

import java.util.ArrayList;
import java.util.List;

/**
 * @author xiaoshiqiang
 * @since 2025/2/8
 */
public class PsiAnnotationUtil {

    /**
     * 获取 PsiField 上的指定注解
     *
     * @param psiField                要检查的 PsiField 对象
     * @param annotationQualifiedName 指定注解的全限定名
     * @return 若找到注解则返回 PsiAnnotation 对象，否则返回 null
     */
    public static PsiAnnotation getAnnotation(PsiField psiField, String annotationQualifiedName) {
        PsiModifierList modifierList = psiField.getModifierList();
        if (modifierList != null) {
            return modifierList.findAnnotation(annotationQualifiedName);
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public static <T> T getAnnotationValue(PsiAnnotation annotation, String attributeName) {
        if (annotation == null || attributeName == null) {
            return null;
        }
        // 获取注解的参数列表
        PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes();
        for (PsiNameValuePair attribute : attributes) {
            if (attributeName.equals(attribute.getName())) {
                PsiElement valueElement = attribute.getValue();
                if (valueElement != null) {
                    if (valueElement instanceof PsiArrayInitializerMemberValue) {
                        // 处理数组类型
                        List<Object> arrayValues = new ArrayList<>();
                        PsiElement[] initializers = ((PsiArrayInitializerMemberValue) valueElement).getInitializers();
                        for (PsiElement initializer : initializers) {
                            if (initializer instanceof PsiLiteralExpression) {
                                Object literalValue = ((PsiLiteralExpression) initializer).getValue();
                                arrayValues.add(literalValue);
                            }
                        }
                        return (T) arrayValues;
                    } else if (valueElement instanceof PsiLiteralExpression) {
                        // 处理基本类型
                        return (T) ((PsiLiteralExpression) valueElement).getValue();
                    }
                }
            }
        }
        return null;
    }

    public static String getAnnotationMemberValue(PsiAnnotationMemberValue memberValue) {
        PsiReference reference = memberValue.getReference();
        if (reference != null) {
            PsiElement resolve = reference.resolve();
            if (resolve instanceof PsiEnumConstant) {
                return ((PsiEnumConstant) resolve).getName();
            }

            if (resolve instanceof PsiField) {
                return PsiFieldUtils.getFieldDefaultValue((PsiField) resolve);
            }
        }

        if (memberValue instanceof PsiClassObjectAccessExpression) {
            PsiTypeElement typeElement = ((PsiClassObjectAccessExpression) memberValue).getOperand();
            return typeElement.getType().getCanonicalText();
        } else if (memberValue instanceof PsiExpression) {
            Object constant = JavaConstantExpressionEvaluator.computeConstantExpression((PsiExpression) memberValue, false);
            return constant == null ? null : constant.toString();
        } else {
            return "";
        }
    }

}
